package com.lml.jdk8.localdate.java8Time;

import org.junit.jupiter.api.Test;

import java.time.*;
import java.util.Set;

/**
 * @author luomingliang
 * @date 2021/9/9 22:01
 */
public class Java8TimeClassMethodDemo {

    /**
     * Date-Time API中的所欲类军声称不可变实例，他们是线程安全的，并且这些类不提供公共构造函数，也就是说没法通过new的方法直接创建，
     * 需要采用工厂发放加以实例化
     * <p>
     * now方法可以根据当前日期或时间创建实例对象
     */
    @Test
    public void test01() {
        //使用now方法创建Instant的实例对象
        Instant instantNow = Instant.now();
        //使用now方法创建LocalDate的实例对象
        LocalDate localDateNow = LocalDate.now();
        //使用now方法创建LocalTime的实例对象
        LocalTime localTimeNow = LocalTime.now();
        //使用now方法创建LocalDateTime的实例对象
        LocalDateTime localDateTimeNow = LocalDateTime.now();
        //使用now方法创建ZonedDateTime的实例对象
        ZonedDateTime zonedDateTimeNow = ZonedDateTime.now();

        //将实例对象打印到控制台查询内容
        System.out.println("instantNow = " + instantNow);
        System.out.println("localDateNow = " + localDateNow);
        System.out.println("localTimeNow = " + localTimeNow);
        System.out.println("localDateTimeNow = " + localDateTimeNow);
        System.out.println("zonedDateTimeNow = " + zonedDateTimeNow);
    }

    /**
     * Year YearMonth MonthDay对象的创建
     */
    @Test
    public void test02() {
        //使用now放创建Year类的实例对象
        Year year = Year.now();
        //使用now放创建YearMonth类的实例对象
        YearMonth yearMonth = YearMonth.now();
        //使用now放创建MonthDay类的实例对象
        MonthDay monthDay = MonthDay.now();

        System.out.println("year = " + year);
        System.out.println("yearMonth = " + yearMonth);
        System.out.println("monthDay = " + monthDay);
    }

    /**
     * LocalDate LocalTime LocalDateTime对象的创建
     */
    @Test
    public void test03() {
        /*
        初识话2018年8月8日的LocalDate对象
         */
        LocalDate localDate = LocalDate.of(2018, 8, 8);
        System.out.println("localDate = " + localDate);

        /*
        初始化晚上8点0分0秒的LocalDate的对象 -> 如果是晚上的时间，需要加12.
        LocalTime.of方法的重载形式有以下几种，可以根据实际情况自行使用
        LocalTime of(int hour, int minute) -> 根据小时/分钟生成对象
        LocalTime of(int hour, int minute, int second) -> 根据小时/分钟/秒生成对象
        LocalTime of(int hour, int minute, int second, int nanoOfSecond) -> 根据小时/分钟/秒/纳秒生成对象
        注意：如果秒和纳秒是0的话，name默认不会封装这些数据，只显示小时和分钟
         */
        LocalTime localTime = LocalTime.of(20, 0, 0, 0);
        System.out.println("localTime = " + localTime);

        /*
        初始化2018年8月8日下午8点0分的LocalDateTime对象
        LocalDateTime.of方法的重载形式有以下几种，可以根据实际情况自行使用
        LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond) -> 根据年/月/日/时/分/秒/纳秒生成对象
        LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute) -> 根据年/月/日/时/分生成对象
         */
        LocalDateTime localDateTime = LocalDateTime.of(2018, 8, 8, 20, 0);
        System.out.println("localDateTime = " + localDateTime);

        /*
        LocalDateTime.of方法的特殊使用：
        LocalDateTime.of(LocalDate date, LocalTime time)
         */
        LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
        System.out.println("localDateTime2 = " + localDateTime2);
    }

    /**
     * 时区对象的创建及使用
     */
    @Test
    public void test04() {
        //获取所有的时区信息
        Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
        for (String availableZoneId : availableZoneIds) {
            System.out.println(availableZoneId);
        }
        //获取当前系统默认的时区信息 -> 中国
        ZoneId zoneId = ZoneId.systemDefault();
        System.out.println("zoneId = " + zoneId);
    }

    /**
     * 为LocalDateTime添加时区信息
     */
    @Test
    public void test05() {
        //1.封装LocalDateTime对象，参数自定义 -> 2018年11月11日 8点54分38秒
        LocalDateTime localDateTime = LocalDateTime.of(2018, 11, 11, 8, 54, 38);
        //2.localDateTime对象现在只是封装了一个时间，并没有时区相关的数据，所以要添加时区信息到对象中，使用atZone()方法。
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai"));
        System.out.println("Asia/Shanghai当前时间是：" + zonedDateTime);

        //3.更改时区查询其他市区的当前时间，通过withZoneSameInstant()方法即可更改。
        ZonedDateTime tokyoZoneDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
        System.out.println("同一时刻，Asia/Tokyo的时间是：" + tokyoZoneDateTime);
    }

    /**
     * Month枚举类的使用
     */
    @Test
    public void test06() {
        //1.初始化LocalDate和LocalDateTime的时候，月份的参数传入枚举类Month -> 2011年5月15日11时11分11秒
        LocalDateTime localDateTime = LocalDateTime.of(2011, Month.MAY, 15, 11, 11, 11);

        //Month枚举类 -> of可以根据传入的数字返回对应的月份枚举
        Month month = Month.of(12);
        System.out.println("month = " + month);
    }

    /**
     * 练习
     * 创建当前时间（不带时区）
     * 创建当前时间（只包含年月日）
     * 创建当前时间（包含年月日时分秒并且带有时区）
     * 创建2012年12月31日7时38分46秒的日期对象 月份使用枚举类表示
     * 创建2012年12月31日的日期对象 月份使用枚举表示
     * 创建7时38分46秒的时间对象
     */
    @Test
    public void practice() {
        //1.创建当前时间（不带时区）
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println("localDateTime = " + localDateTime);
        //2.创建当前时间（只包含年月日）
        LocalDate localDate = LocalDate.now();
        System.out.println("localDate = " + localDate);
        //3.创建当前时间（包含年月日时分秒并且带有时区）
        ZonedDateTime zonedDateTime = ZonedDateTime.now();
        System.out.println("zonedDateTime = " + zonedDateTime);
        //4.创建2012年12月31日7时38分46秒的日期对象 月份使用枚举类表示
        LocalDateTime localDateTime1 = LocalDateTime.of(2012, Month.DECEMBER, 31, 7, 38, 46);
        System.out.println("localDateTime1 = " + localDateTime1);
        //5.创建2012年12月31日的日期对象 月份使用枚举表示
        LocalDateTime localDateTime2 = LocalDateTime.of(2012, Month.of(12), 31, 7, 38, 46);
        System.out.println("localDateTime2 = " + localDateTime2);
        //6.创建7时38分46秒的时间对象
        LocalTime localTime = LocalTime.of(7, 38, 46);
        System.out.println("localTime = " + localTime);
    }
}
